#include <qthread.h>


class Session : public QThread
{
    O_OBJECT

public:

    Session(int session_id, UserHandler *handler);

    ~Session();

    const std::string getLocalUri();

    const std::string getLocalContact();

    const std::string getRemoteContact();

    const std::string getRemoteUri();

    int getSessionID()const
    {
        return m_sessionID;
    }

    /** Call back from handler
     *  Role: UAS
     */
    // service request to handler the request by service instance.
    void serviceRequestReceived(const std::string service_name, const std::string content_type, const void *data);

    /** Call back from service
     *  Role: UAC
     */
    // response received and will notify the application the data received.
    void serviceResponseReceived(const std::string service_name, const std::string content_type, const void *data);

public slots:

    /** Received server's
        response and send the response to the remote
     *  Role: UAS
     */
    void sendServiceResponse(const std::string service_name, const std::string content_type, const void *data);

private:

    int m_sessionID;

    UserHandler *m_handler;

};

void Session::serviceRequestReceived(const std::string service_name, const std::string content_type, const void *data)
{
    connect(ServiceManager::getInstance()->getServiceByName(service_name), SIGNAL(responseIsReady()))
}





#include <qmutex.h>
#include <qmutexlocker.h>
#include <qmap.h>

class SessionManager
{
public:
    static SessionManager *getInstance()
    {
        QMutexLocker(&m_mutex);
        if(m_instance == NULL)
        {
            m_instance = new SessionManager();
        }
        return m_instance;
    }

    SessionManager();

    ~SessionManager();

    void addSession(const Session *session);

    int removeSession(int session_id);

    Session *getSessionByID(int session_id);

    bool hasSessionRunning();

private:

    mutable QMutex m_mutex;

    QMap<int, Session*> *m_sessionList;

    static SessionManager *m_instance;
};

static SessionManager *SessionManager::m_instance = 0;

SessionManager::SessionManager()
{
    if(m_sessionList == NULL)
    {

        m_sessionList = new QMap<int, Session*>();
    }
}

SessionManager::~SessionManager()
{
    if(m_sessionList != NULL)
    {
        if(!m_sessionList->empty())
        {
            QMap<int, Session*>::iterator i = m_sessionList->begin();
            QMap<int, Session*>::iterator j = i;
            while( i != m_sessionList->end())
            {
                j = m_sessionList->erase(i);
                delete i.value();

                i = j;
            }
            // remove error
        }

        delete m_sessionList;
    }
}

int SessionManager::removeSession(int session_id)
{
    QMutexLocker(&m_mutex);

    QMap<int, Session*>::iterator i = m_sessionList->find(session_id);
    if( i == m_sessionList->end())
    {
        return -1;
    }
    int count = m_sessionList->remove(session_id);
    if(count >1)
    {
        // 2 more has same session id
        // can not happen
        return -2;
    }

    delete i.value();
}

int SessionManager::addSession(const Session *session)
{
    QMutexLocker(&m_mutex);

    if(m_sessionList == NULL)
    {
        return -1;
    }

    QMap<int, Session*>::const_iterator i = m_sessionList->find(session->getSessionID());
    if(i != m_sessionList->constEnd())
    {
        //check why has same id
        // this can not happen
        return -1;
    }

    m_sessionList->insert(session->getSessionID(), session);
}

class SessionFactory
{
public:
    SessionFactory(){}

    ~SessionFactory(){}

    /** Note: session delete operation done by SessionManager */
    Session *createSession(int session_id, UserHandler *handler);
};

Session *SessionFactory::createSession(int session_id, UserHandler *handler)
{
    if(handler == NULL)
    {
        return (Session*)0;
    }

    return new Session(session_id, handler);
}




class HttpLikeService
{
    Q_OBJECT

signals:

    void responseIsReady(const std::string service_name, const std::string content_type, const void *data);

};


#include <qmutex.h>
#include <qmutexlocker.h>
#include <qmap.h>

class ActiveServiceManager
{
public:
    static ActiveServiceManager *getInstance()
    {
    }

    ActiveServiceManager();

    ~ActiveServiceManager();

    int addRunningService(const Service *service);

    int removeRunningService(const std::string service_name);

    Service *getServiceByName(const std::string service_name);

    bool hasRunningService();

private:

    QMutex m_mutex;

    static ActiveServiceManager *m_instance;

    QMap<std::string, Service*> *m_activeServiceList;
};


